﻿using Microsoft.Extensions.Options;
using Naruto.FileStorage.Abstractions;
using Naruto.FileStorage.Helper;
using Naruto.Infrastructure.Interface;
using System;
using System.IO;
using System.Threading.Tasks;

namespace Naruto.FileStorage.Provider.Physical
{
    /// <summary>
    /// 从物理磁盘操作
    /// </summary>
    public sealed class PhysicalFileStorage : IFileStorage
    {
        /// <summary>
        /// 获取文件写入的服务
        /// </summary>
        private IFileOperate uploadFile;

        private IOptions<PhysicalFileOptions> options;

        public PhysicalFileStorage(IFileOperate _uploadFile, IOptions<PhysicalFileOptions> _options)
        {
            uploadFile = _uploadFile;
            options = _options;
        }
        /// <summary>
        /// 根据/ 截取文件的路径
        /// </summary>
        /// <param name="fileStream"></param>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public async Task<string> AddFileAsync(Stream fileStream, string fileName)
        {
            if (fileStream == null || fileStream.Length <= 0 || !fileStream.CanRead)
            {
                return default;
            }
            if (string.IsNullOrWhiteSpace(fileName))
                return default;
            //获取文件上传的根地址
            string path = options.Value.UploadFilePath;
            //截取
            var res = fileName.SplitFileName();
            if (res == null)
            {
                return default;
            }
            //目录地址
            var directoryPath = Path.Combine(path, res.DirectoryName);

            //目录不存在就创建一个目录
            if (!Directory.Exists(directoryPath))
            {
                Directory.CreateDirectory(directoryPath);
            }
            //拼接路径
            string savePath = Path.Combine(directoryPath, res.FileName);
            //写入文件
            await uploadFile.UpLoadFileFromStream(fileStream, savePath);
            return fileName;
        }

        /// <summary>
        /// 文件地址的删除
        /// </summary>
        /// <param name="files"></param>
        /// <returns></returns>
        public async Task DeleteFileAsync(string fileName)
        {
            if (string.IsNullOrWhiteSpace(fileName))
                return;
            await Task.Factory.StartNew(() =>
            {
                //拼接文件存放的地址
                var file = Path.Combine(options.Value.UploadFilePath, fileName);
                if (File.Exists(file))
                {
                    File.Delete(file);
                }
            });
        }

        /// <summary>
        /// 获取资源的信息
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public async Task<byte[]> GetFileAsync(string fileName)
        {
            if (string.IsNullOrWhiteSpace(fileName))
                return default;
            var resourcePath = GetResourcePath(fileName);
            if (string.IsNullOrWhiteSpace(resourcePath))
            {
                return default;
            }
            //获取资源
            return await uploadFile.GetFileAsync(resourcePath);
        }

        /// <summary>
        /// 获取资源的物理磁盘地址
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        private string GetResourcePath(string fileName)
        {
            //获取文件上传的根地址
            string path = options.Value.UploadFilePath;
            //截取
            var res = fileName.SplitFileName();
            if (res == null)
            {
                return default;
            }
            //目录地址
            var directoryPath = Path.Combine(path, res.DirectoryName);

            //验证目录是否存在
            if (!Directory.Exists(directoryPath))
            {
                return default;
            }
            //拼接要访问的资源的路径
            string resourcePath = Path.Combine(directoryPath, res.FileName);
            //验证访问的资源是否存在
            if (!File.Exists(resourcePath))
            {
                return default;
            }
            return resourcePath;
        }
    }
}
